package com.kk.xhr.admin.biz.impl;

import com.kk.xhr.admin.biz.IUserBizService;
import com.kk.xhr.admin.controller.request.UserAddRequest;
import com.kk.xhr.admin.controller.request.UserModifyRequest;
import com.kk.xhr.admin.controller.request.UserQueryRequest;
import com.kk.xhr.admin.controller.vo.UserInfoVO;
import com.kk.xhr.admin.controller.vo.UserVO;
import com.kk.xhr.admin.util.FileUtil;
import com.kk.xhr.common.ErrorCodeEnum;
import com.kk.xhr.common.exception.BusinessException;
import com.kk.xhr.common.pojo.EmployeeFromEnum;
import com.kk.xhr.common.pojo.EmployeeStatusEnum;
import com.kk.xhr.common.pojo.UserStatusEnum;
import com.kk.xhr.model.dto.DepartmentDTO;
import com.kk.xhr.model.dto.EmployeeDTO;
import com.kk.xhr.model.dto.LevelDTO;
import com.kk.xhr.model.dto.PageDto;
import com.kk.xhr.model.dto.PositionDTO;
import com.kk.xhr.model.dto.UserDTO;
import com.kk.xhr.model.dto.UserInfoDTO;
import com.kk.xhr.model.dto.UserQueryRequestDTO;
import com.kk.xhr.model.entity.Role;
import com.kk.xhr.model.entity.User;
import com.kk.xhr.model.service.IDepartmentService;
import com.kk.xhr.model.service.IEmployeeService;
import com.kk.xhr.model.service.ILevelService;
import com.kk.xhr.model.service.IPositionService;
import com.kk.xhr.model.service.IRoleService;
import com.kk.xhr.model.service.IUserService;
import com.kk.xhr.web.vo.PageVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户biz服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/11
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
public class UserBizServiceImpl implements IUserBizService {
    private final IUserService userService;
    private final IPositionService positionService;
    private final ILevelService levelService;
    private final IDepartmentService departmentService;
    private final IRoleService roleService;
    private final IEmployeeService employeeService;

    /**
     * {@inheritDoc}
     */
    @Override
    public UserVO getUserInfo(Long userId) {
        UserDTO user = userService.queryNormal(userId)
            .orElseThrow(() -> new BusinessException(ErrorCodeEnum.USER_NOT_EXIST));
        return this.generateVO(user, roleService.queryRolesByUserId(userId)
            .stream()
            .map(Role::getName)
            .collect(Collectors.toSet()));
    }

    /**
     * 分页查询
     *
     * @param request UserQueryRequest
     * @return UserVO
     */
    @Override
    public PageVO<UserVO> queryPage(UserQueryRequest request) {
        PageDto<UserDTO> dtos = userService
            .queryPage(UserQueryRequestDTO.builder()
                .name(request.getName())
                .workId(request.getWorkId())
                .status(request.getStatus())
                .limit(request.getLimit())
                .offset(request.getOffset())
                .build());
        return PageVO.fromDTO(dtos, dto -> {
            String position = positionService.queryById(dto.getPositionId())
                .orElse(PositionDTO.builder().name("待定").build()).getName();
            String level = levelService.queryById(dto.getLevelId())
                .orElse(LevelDTO.builder().level("待定").build()).getLevel();
            String department = departmentService.queryById(dto.getDepartmentId())
                .orElse(DepartmentDTO.builder().name("待定").build()).getName();
            return generateVO(dto, position, level, department, dto.getBossId());
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean add(UserAddRequest request) {
        Long bossId = null;
        if (null != request.getDepartmentId()) {
            DepartmentDTO department = departmentService.queryById(request.getDepartmentId())
                .orElseThrow(() -> new BusinessException(ErrorCodeEnum.DEPARTMENT_NOT_EXIST));
            bossId = department.getUserId();
        }
        User user = userService.queryLast().orElseThrow(() -> new BusinessException(ErrorCodeEnum.USER_NOT_EXIST));
        Long workId = user.getWorkId() + 1;
        Long userId = userService.add(UserDTO.builder()
            .name(request.getName())
            .username(String.valueOf(workId))
            .password(DigestUtils.md5DigestAsHex(String.valueOf(workId).getBytes()))
            .avatarUrl("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif")
            .remark("这个人很懒，什么都没有留下")
            .departmentId(request.getDepartmentId())
            .positionId(request.getPositionId())
            .levelId(request.getLevelId())
            .bossId(bossId)
            .workId(workId)
            .workAge(request.getWorkAge())
            .build());
        employeeService.add(EmployeeDTO.builder()
            .name(request.getName())
            .userId(userId)
            .form(EmployeeFromEnum.OTHER)
            .status(EmployeeStatusEnum.OTHER)
            .build());
        roleService.addUserRole(userId, Collections.singletonList(3L));
        return true;
    }

    @Override
    public boolean modify(Long id, UserModifyRequest request) {
        return userService.modify(UserDTO.builder()
            .id(id)
            .email(request.getEmail())
            .phone(request.getPhone())
            .telephone(request.getTelephone())
            .address(request.getAddress())
            .avatarFileId(request.getAvatarFileId())
            .avatarUrl(request.getAvatarUrl())
            .remark(request.getRemark())
            .departmentId(request.getDepartmentId())
            .positionId(request.getPositionId())
            .levelId(request.getLevelId())
            .workAge(request.getWorkAge())
            .build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean modifyStatus(Long id, UserStatusEnum status) {
        roleService.deleteUserRole(id);
        return userService.modify(id, status);
    }

    @Override
    public List<UserInfoVO> query() {
        List<UserInfoDTO> list = userService.query();
        return list.stream()
            .map(dto -> UserInfoVO.builder()
                .id(dto.getId())
                .workId(dto.getWorkId())
                .name(dto.getName())
                .build())
            .collect(Collectors.toList());
    }

    /**
     * 修改个人信息
     *
     * @param userId  用户id
     * @param request 修改请求
     */
    @Override
    public void modifyMine(Long userId, UserModifyRequest request) {
        userService.modify(UserDTO.builder()
            .id(userId)
            .email(request.getEmail())
            .remark(request.getRemark())
            .build());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String modifyAvatar(Long userId, String fileId) {
        String fileUrl = FileUtil.getFileUrl(fileId);
        userService.modify(UserDTO.builder().id(userId)
            .avatarUrl(fileUrl)
            .build());
        Optional<EmployeeDTO> optional = employeeService.queryByUserId(userId);
        if (optional.isPresent()) {
            EmployeeDTO employee = optional.get();
            employeeService.modify(EmployeeDTO.builder().id(employee.getId()).avatarUrl(fileUrl).build());
        }
        return fileUrl;
    }

    /**
     * vo生成器
     *
     * @param user       用户
     * @param bossId     上级
     * @return UserVO
     */
    private UserVO generateVO(UserDTO user, String position, String level, String department, Long bossId) {
        Set<Role> roles = roleService.queryRolesByUserId(user.getId());
        return UserVO.builder()
            .id(user.getId())
            .name(user.getName())
            .username(user.getUsername())
            .avatar(user.getAvatarUrl())
            .email(user.getEmail())
            .phone(user.getPhone())
            .telephone(user.getTelephone())
            .introduction(user.getRemark())
            .workId(user.getWorkId())
            .workAge(user.getWorkAge())
            .department(department)
            .position(position)
            .level(level)
            .boss(null == bossId ? "无" : userService.queryName(bossId))
            .status(user.getStatus())
            .roles(roles.stream().map(Role::getName).collect(Collectors.toSet()))
            .roleIds(roles.stream().map(Role::getId).collect(Collectors.toSet()))
            .build();
    }

    /**
     * vo生成器
     *
     * @param user  用户
     * @param roles 角色
     * @return UserVO
     */
    private UserVO generateVO(UserDTO user, Set<String> roles) {
        return UserVO.builder()
            .id(user.getId())
            .name(user.getName())
            .avatar(user.getAvatarUrl())
            .introduction(user.getRemark())
            .email(user.getEmail())
            .roles(roles)
            .build();
    }

}
